{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 给定一个净值序列，计算年化收益、最大回撤、夏普比率"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  数据准备：净值序列"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 计算净值序列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "pd.set_option('display.max_rows', 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2019-01-02    1.000000\n",
       "2019-01-03    0.998417\n",
       "2019-01-04    1.022337\n",
       "2019-01-07    1.028543\n",
       "2019-01-08    1.026321\n",
       "                ...   \n",
       "2019-12-25    1.343935\n",
       "2019-12-26    1.355762\n",
       "2019-12-27    1.354429\n",
       "2019-12-30    1.374499\n",
       "2019-12-31    1.379534\n",
       "Name: close, Length: 244, dtype: float64"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 获取HS300每日收盘价，时间：2015-01-01至2018-12-31\n",
    "df = read_csv('GuizhouMoutai.csv')[close]\n",
    "\n",
    "# 净值统计：以第一个交易日收盘价为参考，计算每日净值\n",
    "first_close = df['close'][0]\n",
    "net_values = df['close']/ first_close\n",
    "net_values"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 根据日净值分别计算年化收益、最大回撤、夏普比率"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  计算年化收益\n",
    "\n",
    "- 计算公式\n",
    "\n",
    "    $ Total Annualized Returns=Rp= ((1+P)^{\\frac{245}{n}}−1) * 100\\%  $\n",
    "\n",
    "    $ P=策略收益 $\n",
    "\n",
    "    $ n=策略执行天数 $"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_annual_profit(days, net_value):\n",
    "    \"\"\"\n",
    "    计算年化收益\n",
    "    \"\"\"\n",
    "\n",
    "    annual_profit = 0\n",
    "    # 交易日数大于0，才计算年化收益\n",
    "    if days > 0:\n",
    "        # 计算年数\n",
    "        years = days / 245\n",
    "        # 计算年化收益\n",
    "        annual_profit = pow(net_value, 1 / years) - 1\n",
    "\n",
    "    # 将年化收益转化为百分数，保留两位小数\n",
    "    annual_profit = round(annual_profit * 100, 2)\n",
    "\n",
    "    return annual_profit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "年化收益率: 38.14 %\n"
     ]
    }
   ],
   "source": [
    "print('年化收益率:', compute_annual_profit(len(df), net_values[-1]), \"%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 计算最大回撤\n",
    "\n",
    "~~~\n",
    "描述策略可能出现的最糟糕的情况，最极端可能的亏损情况。\n",
    "\n",
    "~~~\n",
    "\n",
    "\n",
    "- 计算公式\n",
    "\n",
    "    $ Max Drawdown=Max(Px−Py)/Px $\n",
    "\n",
    "    $ Px,Py=策略某日净值，y>x $ "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_drawdown(net_values):\n",
    "    \"\"\"\n",
    "    计算最大回撤\n",
    "    :param net_values: 净值列表\n",
    "    \"\"\"\n",
    "    # 最大回撤初始值设为0\n",
    "    max_drawdown = 0\n",
    "    index = 0\n",
    "    # 双层循环找出最大回撤\n",
    "    for net_value in net_values:\n",
    "        # 计算从当前开始直到结束，和当前净值相比的最大回撤\n",
    "        for sub_net_value in net_values[index:]:\n",
    "            # 计算回撤\n",
    "            drawdown = 1 - sub_net_value / net_value\n",
    "            # 如果当前的回撤大于已经计算的最大回撤，则当前回撤作为最大回撤\n",
    "            if drawdown > max_drawdown:\n",
    "                max_drawdown = drawdown\n",
    "        index += 1\n",
    "    return max_drawdown\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最大回撤: 13.49 %\n"
     ]
    }
   ],
   "source": [
    "max_drawdown = compute_drawdown(list(net_values))\n",
    "print('最大回撤:', round(max_drawdown * 100, 2), \"%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 计算夏普比率\n",
    "\n",
    "~~~\n",
    "表示每承受一单位总风险，会产生多少的超额报酬，可以同时对策略的收益与风险进行综合考虑。\n",
    "~~~\n",
    "\n",
    "- 计算公式\n",
    "\n",
    "    $ Sharpe Ratio = \\frac{R_p - R_f}{\\sigma_p \\times \\sqrt{ 245}  } $ \n",
    "    \n",
    "    $ R_p = 策略年化收益率  $\n",
    "    \n",
    "    $ R_f = 无风险利率  $\n",
    "    \n",
    "    $ \\sigma_p = 策略收益波动率  $\n",
    "    \n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_sharpe_ratio(net_values):\n",
    "    \"\"\"\n",
    "    计算夏普比率\n",
    "    :param net_values: 净值列表\n",
    "    \"\"\"\n",
    "\n",
    "    # 总交易日数\n",
    "    trading_days = len(net_values)\n",
    "    # 所有收益的DataFrame\n",
    "    profit_df = pd.DataFrame(columns={'profit'})\n",
    "    # 收益之后，初始化为第一天的收益\n",
    "    profit_df.loc[0] = {'profit': round((net_values[0] - 1) * 100, 2)}\n",
    "    # 计算每天的收益\n",
    "    for index in range(1, trading_days):\n",
    "        # 计算每日的收益变化\n",
    "        profit = (net_values[index] - net_values[index - 1]) / net_values[index - 1]\n",
    "        profit = round(profit * 100, 2)\n",
    "        profit_df.loc[index] = {'profit': profit}\n",
    "\n",
    "    \n",
    "\n",
    "    # 计算当日收益标准差\n",
    "    profit_std = pow(profit_df['profit'].var(), 1 / 2)\n",
    "\n",
    "    # 年化收益\n",
    "    annual_profit = compute_annual_profit(trading_days, net_values[-1])\n",
    "\n",
    "    # 夏普比率\n",
    "    sharpe_ratio = (annual_profit - 4.75) / (profit_std * pow(245, 1 / 2))\n",
    "\n",
    "    return sharpe_ratio\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "夏普比率: 1.711\n"
     ]
    }
   ],
   "source": [
    "sharp = compute_sharpe_ratio(list(net_values))\n",
    "print('夏普比率:', round(sharp,3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 习题：根据HS300周净值序列， 分别计算年化收益、最大回撤、夏普比率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2019-01-08    1.000000\n",
       "2019-01-15    1.026344\n",
       "2019-01-22    1.031374\n",
       "2019-01-29    1.047994\n",
       "2019-02-12    1.092739\n",
       "                ...   \n",
       "2019-12-04    1.263189\n",
       "2019-12-11    1.280556\n",
       "2019-12-18    1.323221\n",
       "2019-12-25    1.309469\n",
       "2019-12-31    1.344155\n",
       "Name: close, Length: 49, dtype: float64"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 样例： 从聚宽JQData获取HS300的周K数据\n",
    "\n",
    "# ID是申请时所填写的手机号；Password为聚宽官网登录密码\n",
    "# auth('ID','Password') \n",
    "\n",
    "pd.set_option('display.max_rows', 10)\n",
    "\n",
    "# 获取HS300周K收盘价\n",
    "df = get_price('000300.XSHG', start_date='2019-01-01', end_date='2019-12-31', frequency='5d', fields=['close'], skip_paused=False, fq='pre')\n",
    "first_close = df['close'][0]\n",
    "net_values = df['close']/ first_close\n",
    "net_values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.9.10 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "MarkDown菜单",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "vscode": {
   "interpreter": {
    "hash": "2188e1cc1a9989a421970a661e43d4f741f1513397d33b4fbf3b1bb0bf8e5d97"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
